home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1993 / MacHack 1993.toast / MacHack™ 1987-1992 / MacHack™ '90 / Source Code ƒ / MPW C ƒ / Func names ƒ / FuncNames.c next >
Encoding:
C/C++ Source or Header  |  1989-01-12  |  35.4 KB  |  1,604 lines  |  [TEXT/MPS ]

  1. /* ********************************************************************
  2.  
  3.     FuncNames  -  A 'C' Function Listing Utility for MPW
  4.  
  5.     Version 1.0   January 12, 1989
  6.  
  7.     Copyright (c) 1989 by Scott Boag
  8.  
  9.     Changes and Additions to XC.C Copyright (c) 1989 by Scott Boag
  10.  
  11.         Scott Boag
  12.         DMR Group Inc.
  13.         57 River Street
  14.         Wellesly Hill, Massachusetts
  15.         02181
  16.         (617) 237-0087
  17.  
  18.     Permission granted to copy for non-commercial purporses.
  19.  
  20. --------------------------------------------------------
  21.     Derived from:
  22.     
  23.         XC.C
  24.  
  25.         Version 1.0   January, 1982
  26.     
  27.         Copyright (c) 1982 by Philip N. Hisley
  28.     
  29.             Philip N. Hisley
  30.             548H Jamestown Court
  31.             Edgewood, Maryland 21040
  32.             (301) 679-4606
  33.  
  34.     Released for non-commercial distribution only
  35.  
  36.     Converted to IBM/PC CI/C86 by David N. Smith, May/June 1983
  37.     with enhancements and Lattice compiler support in December 1983.
  38.  
  39.         David N. Smith
  40.         44 Ole Musket Lane
  41.         Danbury, CT 06810
  42.         (203) 748-5934
  43.         CompuServe: 73145,153
  44.  
  45.     Changes Copyright (c) 1983 by David N. Smith
  46.     Permission granted to copy for non-commercial purporses.
  47.  
  48.     PC Enhancements include:
  49.  
  50.         1)  Nested #INCLUDE statements
  51.         2)  Single spaced cross-reference list
  52.         3)  Removal of tabbing on output device
  53.             (Since many printers don't support it)
  54.         4)  #INCLUDE statements with both "--" and <-->
  55.             syntax and with a full fileid in the quotes.
  56.         5)  Multiple input filenames on command line.
  57.  
  58.  
  59.  
  60.  
  61.     Minor additions by John Beamish, June 1984
  62.  
  63.         John Beamish
  64.         Box 340, Station T
  65.         Toronto, Ontario
  66.         M6B 4A3
  67.         (416) 782-1770
  68.  
  69.     Changes Copyright (c) 1984 by John Beamish.
  70.     Permission granted to copy for non-commercial purposes.
  71.  
  72.     1.    Added reserved words ENUM and VOID.
  73.     2.    Variable names extended to 31 characters.
  74.     3.    Tab option on command line.  Tabs are expanded to number
  75.         of spaces specified in value with -t flag.  Default is 4.
  76.     4.    Cross-reference prints a blank line when the first
  77.         character changes.
  78.     5.  Command line errors reported in a more descriptive fashion.
  79.     6.    Listing "tidied-up" and some comments added.
  80.  
  81. --------------------------------------------------------
  82.  
  83.     A good way to see how this program works is to use it on itself.
  84.     For example:
  85.  
  86.         FuncNames FuncNames.c -i > prn
  87.  
  88.     will run the program on itself, include the #include files
  89.     and direct the output to the printer.
  90.  
  91.     Abstract:
  92.     
  93.         'FuncNames' is primarly a function indexing utility and
  94.         is meant to provide a printout or on-line reference 
  95.         to large source files.  It is best used with the 
  96.         -f or -p flags set.
  97.  
  98.         'FuncNames' is also a cross-reference utility for 'C' programs.
  99.         It has the ability to handle nested include files
  100.         to a depth of 8 levels and properly processes nested
  101.         comments as supported by BDS C. 
  102.  
  103.         Usage: FuncNames <filename> <flag(s)>
  104.  
  105.          Flags: -f                = List function position by Files and Lines.
  106.                 -p              = List functions position by Files, Lines, and pages.
  107.                 -m              = List Macros along with functions.
  108.                 -x              = Do Cross-reference (excludes function listing)
  109.                 -i              = Enable file inclusion (dependent on -x being set)
  110.                 -l              = Generate listing only (dependent on -x being set)
  111.                 -r              = Cross-reference reserved words (dependent on -x being set)
  112.                 -o <outfile>    = Write output to named file\n");
  113.                 -t <tab width>  = Number of spaces to expand tabs\n");
  114.                 -w <width>      = Width of output page\n\n");
  115.  
  116.         Note that flags -o -w -t must be followed by a space
  117.         and then the value for the flag.
  118.  
  119.    ******************************************************************** */
  120.  
  121. #include    <types.h>
  122. #include    <stdio.h>
  123. #include    <ErrMgr.h>
  124. #include    <Errors.h>
  125. #include    <CursorCtl.h>
  126. #include    <CType.h>
  127. #include    <String.h>
  128. #include    <Strings.h>
  129.  
  130. /* Compiler specific stuff */
  131.  
  132. /*
  133. #define Lattice
  134. #ifdef Lattice
  135. #include "e:ctype.h"
  136. #endif
  137. */
  138.  
  139. /* end compiler specific section */
  140.  
  141.  
  142.  
  143. /************************************************************************
  144.  * #defines
  145.  ************************************************************************/
  146. #ifndef        TRUE
  147. #define        TRUE        1
  148. #define        FALSE        0
  149. #endif
  150.  
  151.                 /* I use a Gemini 10X in compressed            */
  152.                 /* print, 8 lpi most of the time.  Using    */
  153.                 /* this define allows me to use the            */
  154.                 /* complete printed page for listings        */
  155. /*
  156. #define        PAGE_128X80
  157. */
  158. #ifdef        PAGE_128X80
  159. #define        LINES_PER_PAGE  80
  160. #define        REFS_PER_LINE   15
  161. #define        MAX_COL           128
  162. #else
  163. #define        LINES_PER_PAGE  60    /* printed lines per page                    */
  164. #define        REFS_PER_LINE    8    /* maximum refs per line                     */
  165. #define        MAX_COL            78    /* default max col nmbr for listing line     */
  166. #endif
  167.  
  168. #define        MIN_COL    30        /* minimum value for -w option                 */
  169. #define        MIN_TAB     2
  170. #define        MAX_TAB    10
  171. #define        MAX_REF     5        /* maximum refs per ref-block                 */
  172. #define        MAX_LEN    32        /* maximum identifier length                */
  173. #define        MAX_WRD   749        /* maximum number of identifiers             */
  174. #define        MAX_ALPHA  53        /* maximum alpha chain heads                 */
  175. #define        ERROR       -1
  176. #define        FF         0x0C        /* formfeed                                 */
  177. #define        TAB         4
  178. #define        TABCHAR         0x09
  179. #define     SPACECHAR        0x20
  180.  
  181. #define        OPENCURLY    0x7B
  182. #define        CLOSECURLY    0x7D
  183. #define        OPENPAREN    0x28
  184. #define        CLOSEPAREN    0x29
  185. #define        SEMICOLEN    0x3B
  186.  
  187.  
  188. /************************************************************************
  189.  * Global_variables
  190.  ************************************************************************/
  191. struct    rf_blk {
  192.     int        ref_item[MAX_REF];
  193.     char*    ref_cnt;
  194. } onerf;
  195.  
  196. struct    id_blk {
  197.     char    id_name[MAX_LEN];
  198.     int        func_ref;
  199.     struct    id_blk *alpha_lnk;
  200.     struct    rf_blk *top_lnk;
  201.     struct    rf_blk *lst_lnk;
  202. } oneid;
  203.  
  204. struct    id_blk *id_vector[MAX_WRD];
  205.  
  206. struct    alpha_hdr {
  207.         struct id_blk *alpha_top;
  208.         struct id_blk *alpha_lst;
  209. };
  210.  
  211. struct    alpha_hdr alpha_vector[MAX_ALPHA];
  212.  
  213. int    pagno;                    /* page number                                */
  214. int    paglin;                 /* page line counter                        */
  215. int    linum;                    /* line number                                */
  216. int    edtnum;                 /* edit line number                            */
  217. int    fil_cnt;                /* active file index                        */
  218. int    wrd_cnt;                /* token count                                */
  219. int    id_cnt;                 /* number of unique identifiers                */
  220. int    rhsh_cnt;                /* number of conflict hits                    */
  221. int    filevl;                 /* file level                                */
  222. int    dummy;                    /* dummy integer                            */
  223. int    max_col=MAX_COL;        /* maximum right column for listing line    */
  224. int tab=TAB;                /* standard tab expansion                    */
  225. int    prt_ref;
  226.  
  227. /* Variables local to this file */
  228.  
  229. #define    FBUFSIZ    8*BUFSIZ
  230.  
  231. static    Boolean    optionsSpecified;
  232. static    Boolean    lineOption;
  233. static    Boolean    charOption;
  234. static    char    errorBuffer[256];        /* space to store text from GetSysErrText */
  235. static    char    filebuffer[FBUFSIZ];    /* buffer used for I/O */
  236.  
  237. int        echo_flag;
  238.  
  239. int        curlybrack_cnt;
  240. int        parenbrack_cnt;
  241.  
  242. int        found_prob_func;
  243. int        found_function;
  244.  
  245. int        found_macro;
  246. int        wrote_macro;
  247.  
  248. int        func_count;
  249.  
  250. int        structflag;
  251.  
  252. int        defineflag;
  253.  
  254. int        continuedefineflag;
  255.  
  256. int        nofuncnameflag;
  257.  
  258. int        prevchar;
  259. int        lastnonspacechar;
  260.  
  261. char    act_fil[MAX_LEN];
  262. char    lst_fil[MAX_LEN];
  263. char    gbl_fil[MAX_LEN];
  264. FILE    *f_lst_fil;
  265. int        i_flg,
  266.         l_flg,
  267.         o_flg,
  268.         r_flg,
  269.         f_flg,
  270.         m_flg,
  271.         p_flg;
  272.  
  273.  
  274. /************************************************************************
  275.  * Prototypes. 
  276.  ************************************************************************/
  277. int main(int p_argc, char **p_argv);
  278. int lst_err(void);
  279. int use_err(int x, char* commandname);
  280. int proc_file(char *filnam, int incnum);
  281. void get_include_fileid(char *token, FILE *infile, char *filename, int linenumber);
  282. void echo(char c);
  283. void echochar(char c);
  284. int get_token(FILE *infile, char *g_token, int *g_toklen, int *g_eoflg, int g_flg);
  285. int fil_chr(FILE *infile, int *f_eof);
  286. int rdchr(FILE *infile, int *r_eoflg, int rd_flg);
  287. int chk_token(char *c_token);
  288. void put_token(char *p_token, int p_ref);
  289. void chain_alpha(struct id_blk *ca_ptr, char *ca_token);
  290. struct id_blk *alloc_id(char *aid_token);
  291. struct rf_blk *alloc_rf(int arf_ref);
  292. struct rf_blk *add_rf(struct rf_blk *adr_ptr, int adr_ref);
  293. void prnt_tbl(void);
  294. void prt_hdr(void);
  295. void nl(void);
  296. int abs(int i);
  297. long atoi(char *s);
  298. char *alloc(int i);
  299. void check_paren(char c);
  300.  
  301. /* This should be declared somewhere, but I don't find it... */
  302. char* malloc(int i);
  303.  
  304. /************************************************************************
  305.  * Function: main
  306.  ************************************************************************/
  307. int main(p_argc, p_argv)
  308.     int        p_argc;
  309.     char    **p_argv;
  310.  
  311.     {
  312.     char    *arg;
  313.     int        argc;
  314.     char    **argv;
  315.     char    c;
  316.     int        i;
  317.     int        fileliststart;
  318.     long    files;
  319.     long    parms;
  320.  
  321.     argc = p_argc;
  322.     argv = p_argv;
  323.     if (argc < 2){
  324.         use_err('f', p_argv[0]);
  325.     }
  326.     files = func_count = 0;
  327.     p_flg = m_flg = f_flg = i_flg=l_flg=o_flg=r_flg=FALSE;
  328.     echo_flag = nofuncnameflag = TRUE;
  329.     for (parms = 1; parms < argc; parms++) {
  330.         if (*(arg=*++argv) != '-') {
  331.             p_argv[++files] = p_argv[parms];
  332.         }
  333.         else {
  334.             switch(*++arg) {
  335.                 case 'i':
  336.                 case 'I':
  337.                     /* -i = Enable file inclusion */
  338.                     i_flg++;
  339.                     break;  
  340.                 case 'l':
  341.                 case 'L':
  342.                     /* -l = Generate listing only */
  343.                     l_flg++;
  344.                     break;
  345.                 case 'o':
  346.                 case 'O':
  347.                     /* -o <filename> = Write output to named file */
  348.                     {
  349.                         o_flg++;
  350.                         if (--argc == 0) {
  351.                             use_err('o', p_argv[0]);
  352.                         }
  353.                         strcpy(lst_fil,*++argv);
  354.                         if (lst_fil[0] == '-') {
  355.                             use_err('o', p_argv[0]);
  356.                         }
  357.                         break;
  358.                     }
  359.                 case 'r':
  360.                 case 'R':
  361.                     /* -r = Cross-ref reserved words */
  362.                     r_flg++;
  363.                     break;
  364.                 case 'x':
  365.                 case 'X':
  366.                     /* -f = do cross reference */
  367.                     nofuncnameflag = FALSE;
  368.                     echo_flag = FALSE;
  369.                     break;
  370.                 case 'p':
  371.                 case 'P':
  372.                     /* -p = list page numbers */
  373.                     p_flg++;
  374.                     break;
  375.                 case 'm':
  376.                 case 'M':
  377.                     /* -m = list macros */
  378.                     m_flg++;
  379.                     break;
  380.                 case 'f':
  381.                 case 'F':
  382.                     /* -f = list files and numbers */
  383.                     f_flg++;
  384.                     break;
  385.                 case 't':
  386.                 case 'T':
  387.                     /* -t <number> = Number of spaces to expand each tab */
  388.                     {
  389.                         if (--argc == 0) {
  390.                             use_err('t', p_argv[0]);
  391.                         }
  392.                         i = atoi(*++argv);
  393.                         if (i < MIN_TAB || i > MAX_TAB){
  394.                             use_err('t', p_argv[0]);
  395.                         }
  396.                         tab = i;
  397.                         break;
  398.                     }
  399.                 case 'w':
  400.                 case 'W':
  401.                     /* -w <width> = No of output columns */
  402.                     {
  403.                         if (--argc == 0) {
  404.                             use_err('w', p_argv[0]);
  405.                         }
  406.                         i = atoi(*++argv);
  407.                         if (i <= MIN_COL || i >= 255) {
  408.                             use_err('w', p_argv[0]);
  409.                         }
  410.                         max_col = i;
  411.                         break;
  412.                     }
  413.                     
  414.                 default:
  415.                     use_err('x', p_argv[0]);
  416.             }
  417.         }
  418.     }
  419.  
  420.     if (o_flg) {
  421.         if ((f_lst_fil=fopen(lst_fil,"w")) == NULL) {
  422.             printf("ERROR: Unable to create list file - %s\n",lst_fil);
  423.             exit(0);
  424.         }
  425.         printf("%s ... 'C' Function Lister Utility  v1.0a\n\n", p_argv[0]);
  426.     }
  427.  
  428.     /* initialize id_vector to NULL */
  429.     for (linum=0; linum < MAX_WRD; linum++) {
  430.         id_vector[linum] = NULL;
  431.     }
  432.     
  433.     /* initialize alpha_vector[].top and alpha_vector[].alpha_lst to NULL */
  434.     for (linum=0; linum < MAX_ALPHA; linum++) {
  435.         alpha_vector[linum].alpha_top = alpha_vector[linum].alpha_lst = NULL;
  436.     }
  437.  
  438.     /* More initialization. */
  439.     prt_ref = FALSE;
  440.     fil_cnt = wrd_cnt = linum = 0;
  441.     filevl=paglin=pagno=edtnum=0;
  442.     id_cnt=rhsh_cnt=0;
  443.  
  444.     /* Loop through each of the files in argument list. */
  445.     argc = p_argc;
  446.     argc--;
  447.     argv = p_argv;
  448.     for (parms = 1; parms <= files; parms++) {
  449.         strcpy(gbl_fil,*++argv);
  450.         /* If we run into a '-', then we know we've 
  451.          * hit a flag argument, so it's time to stop. */
  452.         if (*gbl_fil == '-'){
  453.             break;
  454.         }
  455.         /* and cross-ref the file. */
  456.         proc_file(gbl_fil,dummy);
  457.     }
  458.     
  459.     if(nofuncnameflag){
  460.         if(files > 1){
  461.             printf("### %d functions in %d files\n", func_count, files);
  462.         }
  463.         else if(files == 1){
  464.             printf("### %d functions in file\n", func_count);
  465.         }
  466.     }
  467.     
  468.     if (!l_flg) {
  469.         gbl_fil[0] = '\0';
  470.         prnt_tbl();
  471.         if(!echo_flag){
  472.             printf("\nAllowable Symbols: %d\n",MAX_WRD);
  473.             printf("Unique    Symbols: %d\n",id_cnt);
  474.         }
  475.     }
  476.     if (o_flg) {
  477.         nl();
  478. /*
  479.         if (fprintf(f_lst_fil,"%c",CPMEOF) == ERROR){
  480.             lst_err();
  481.         }
  482. */
  483.         fclose(f_lst_fil);
  484.     }
  485. }
  486.  
  487. /************************************************************************
  488.  * Function: lst_err
  489.  ************************************************************************/
  490. int lst_err()
  491. {
  492.     printf("\nERROR: Write error on list output file - %s\n", lst_fil);
  493.     exit(0);
  494. }
  495.  
  496. /************************************************************************
  497.  * Function: use_err
  498.  ************************************************************************/
  499. int use_err(x, commandname)
  500. int        x;
  501. char*    commandname;
  502. {
  503.     printf("\nERROR: Invalid parameter specification.  ");
  504.     if (x == 'f')
  505.         {
  506.         printf("No/invalid input file name specified.");
  507.         }
  508.     else {
  509.         if (x == 'x') {
  510.             printf("Switch not recognized.");
  511.         }
  512.         else {
  513.             printf("Error in switch %c.",x);
  514.         }
  515.     }
  516.     printf("\n\nUsage: %s filename1 <filename2>... <flag(s)>\n\n", commandname);
  517.     printf("Flags: -f               = List function position by Files and Lines.\n");
  518.     printf("       -p              = List functions position by Files, Lines, and pages.\n");
  519.     printf("       -m              = List Macros along with functions.\n");
  520.     printf("       -x              = Do Cross-reference (excludes function listing)\n");
  521.     printf("       -i              = Enable file inclusion (dependent on -x being set)\n");
  522.     printf("       -l              = Generate listing only (dependent on -x being set)\n");
  523.     printf("       -r              = Cross-reference reserved words (dependent on -x being set)\n");
  524.     printf("       -o <outfile>    = Write output to named file\n");
  525.     printf("       -t <tab width>  = Number of spaces to expand tabs\n");
  526.     printf("       -w <width>      = Width of output page\n\n");
  527.     printf("Flags must follow all input file names\n\n");
  528.     printf("Flags -o, -t and -w must be followed by\n");
  529.     printf("a space and then the value of the flag.\n\n");
  530.     exit(0);
  531. }
  532.  
  533. /************************************************************************
  534.  * Function: printfuncline
  535.  ************************************************************************/
  536. void    printfuncline(filename, funcname, func_lineno, func_pageno, macroflag)
  537.  char*    filename;
  538.  char*    funcname;
  539.  int    func_lineno;
  540.  int    func_pageno;
  541.  int    macroflag;
  542.  {
  543.      char*    nmstring = "           ";
  544.      char*    mmstring = " (macro)   ";
  545.     char*    mstring;
  546.  
  547.      if(macroflag){
  548.         mstring = mmstring;
  549.     }
  550.     else {
  551.         mstring = nmstring;
  552.     }
  553.     if(*funcname){
  554.         if(p_flg){
  555.             if (o_flg) {
  556.                 if (fprintf(    f_lst_fil,
  557.                                 "%-24.23s %s File %s ;\tLine %d; ##page %d\n", 
  558.                                 funcname, mstring, filename, 
  559.                                 func_lineno, func_pageno) == ERROR){
  560.                     lst_err();
  561.                 }
  562.                 *funcname = 0x00;
  563.             }
  564.             else {
  565.                 printf("%-24.23s %s File %s ; Line %d; \t##page %d\n", 
  566.                                 funcname, mstring, filename, 
  567.                                 func_lineno, pagno);
  568.             }
  569.         }
  570.         else if(f_flg){
  571.             if (o_flg) {
  572.                 if (fprintf(    f_lst_fil,
  573.                                 "%-24.23s %s File %s ; Line %d\n", 
  574.                                 funcname, mstring, filename, 
  575.                                 func_lineno) == ERROR){
  576.                     lst_err();
  577.                 }
  578.                 *funcname = 0x00;
  579.             }
  580.             else {
  581.                 printf(    "%-24.23s %s File %s ; Line %d\n", 
  582.                         funcname, mstring, filename, func_lineno);
  583.             }
  584.         }
  585.         else {
  586.             if (o_flg) {
  587.                 if (fprintf(f_lst_fil, "%s\n", funcname) == ERROR){
  588.                     lst_err();
  589.                 }
  590.                 *funcname = 0x00;
  591.             }
  592.             else {
  593.                 printf("%s\n", funcname);
  594.             }
  595.         }
  596.         func_count++;
  597.     }
  598. }
  599.  
  600.  
  601. /************************************************************************
  602.  * Function: proc_file
  603.  * Main cross-ref function.
  604.  * (recursive)
  605.  ************************************************************************/
  606. int proc_file(filnam,incnum)
  607. char        *filnam;    /* input filename. */
  608. int            incnum;        /* prev. included line nmbr (return to caller)    */
  609. {
  610.     char        token[MAX_LEN]; /* token buffer                            */
  611.     int            eof_flg;        /* end-of-file indicator                */
  612.     int            tok_len;        /* token length                         */
  613.     FILE        *infile;        /* input file                            */
  614.     char        *worksp;
  615.     char        probable_func[MAX_LEN];
  616.     int            probable_func_lineno;
  617.     int            probable_func_pageno;
  618.  
  619.     strcpy(act_fil,filnam);
  620.     edtnum=0;
  621.     worksp=alloc(66);
  622. /*
  623.     filnam=makefnam(filnam,".c",worksp);
  624. */
  625.     if ((infile=fopen(filnam,"r")) == NULL) {
  626.         printf("\nERROR: Unable to open input file: %s\n",filnam);
  627.         return(incnum);
  628.     }
  629.     free(worksp);    /* ??? */
  630.     if (filevl++ == 0) {
  631.         prt_hdr();
  632.     }
  633.     eof_flg = FALSE;
  634.     parenbrack_cnt = curlybrack_cnt = 0;
  635.     wrote_macro = found_macro = continuedefineflag = defineflag = structflag = 
  636.                     found_function = found_prob_func = FALSE;
  637.     *probable_func = 0x00;
  638.     probable_func_pageno = probable_func_lineno = 0;
  639.     if(nofuncnameflag){
  640.         pagno = 1;
  641.     }
  642.     do {
  643.         if (get_token(infile, token, &tok_len, &eof_flg, 0)){
  644.             if (chk_token(token)) {
  645.                 if (!strcmp(token,"#include")) {
  646.                     get_include_fileid(token, infile, filnam, edtnum);
  647.                     if (!i_flg) {
  648.                         continue;
  649.                     }
  650.                     else {
  651.                         nl();
  652.                         edtnum=proc_file(token,edtnum);
  653.                         strcpy(act_fil,filnam);
  654.                         continue;
  655.                     }
  656.                 }
  657.  
  658.                 if(nofuncnameflag && found_prob_func){
  659.                     strcpy(probable_func, token);
  660.                     probable_func_lineno = edtnum;
  661.                     probable_func_pageno = pagno;
  662.                     found_prob_func = FALSE;
  663.                 }
  664.                 if(defineflag && found_macro && m_flg && !wrote_macro) {
  665.                     printfuncline(filnam, token, edtnum, pagno, TRUE);
  666.                     found_macro = FALSE;
  667.                     wrote_macro = TRUE;
  668.                 }
  669.                 if(nofuncnameflag && found_function){
  670.                     printfuncline(filnam, probable_func, probable_func_lineno, probable_func_pageno, FALSE);
  671.                     found_function = FALSE;
  672.                 }
  673.                 if(!nofuncnameflag){
  674.                     put_token(token,linum);
  675.                 }
  676.             }
  677.         }
  678.         else {
  679.             if(nofuncnameflag && found_prob_func){
  680.                 strcpy(probable_func, token);
  681.                 probable_func_lineno = edtnum;
  682.                 probable_func_pageno = pagno;
  683.                 found_prob_func = FALSE;
  684.             }
  685.         }
  686.     } while (!eof_flg);
  687.  
  688.     filevl -= 1;
  689.     fclose(infile);
  690.  
  691.     return(incnum);
  692. }
  693.  
  694. /************************************************************************
  695.  * Function: check_paren
  696.  ************************************************************************/
  697.  void check_paren(c)
  698.  char    c;
  699.  {
  700.     switch(c){
  701.         case OPENCURLY:
  702.             if(        (!curlybrack_cnt) && 
  703.                     (!parenbrack_cnt) && 
  704.                     (!defineflag) && 
  705.                     (!structflag)){
  706.                 found_function = TRUE;
  707.             }
  708.             curlybrack_cnt++;
  709.             break;
  710.         case CLOSECURLY:
  711.             curlybrack_cnt--;
  712.             if(!curlybrack_cnt) {
  713.                 found_prob_func = found_function = FALSE;
  714.             }
  715.             break;
  716.         case OPENPAREN:
  717.             if(        (!curlybrack_cnt) && 
  718.                     (!parenbrack_cnt) && 
  719.                     (!defineflag) && 
  720.                     (!structflag)){
  721.                 found_prob_func = TRUE;
  722.             }
  723.             else if(defineflag && isalpha(prevchar) && (!parenbrack_cnt)){
  724.                 found_macro = TRUE;
  725.             }
  726.             parenbrack_cnt++;
  727.             break;
  728.         case CLOSEPAREN:
  729.             parenbrack_cnt--;
  730.             break;
  731.     }
  732.     if(!isspace(prevchar)) {
  733.         lastnonspacechar == prevchar;
  734.     }
  735.     prevchar = c;
  736.     return;
  737.  }
  738.  
  739. /************************************************************************
  740.  * Function: get_include_fileid
  741.  ************************************************************************/
  742. void get_include_fileid(token,infile, filename, linenumber)
  743. char        *token;
  744. FILE        *infile;
  745. char        *filename;
  746. int            linenumber;
  747. {
  748.  
  749.     char        c, term;
  750.  
  751.     while (term=getc(infile)){
  752.         if(!isspace(c)) {
  753.             lastnonspacechar == c;
  754.         }
  755.         if(term == EOF){
  756.             break;
  757.         }
  758.         echo(term);
  759.         check_paren(term);
  760.         if(term > SPACECHAR) {
  761.             break;
  762.         }
  763.     }
  764.  
  765.     if ( term == '<' ) {
  766.         term='>';                /* terminator is > or "                    */
  767.     }
  768.     if ( (term != '>') && (term!='"') ) {
  769.         printf("Error scanning #INCLUDE fileid: %c; file %s; line %d\n", 
  770.                                 term, filename, linenumber);
  771.         exit(1);
  772.     }
  773.  
  774.     do {
  775.         if ( (c = getc(infile)) != ' ') {
  776.             check_paren(c);
  777.             *token++ = c;
  778.             echo(c);
  779.         }
  780.         else{
  781.             echo(c);
  782.         }
  783.     } while ( c != term );
  784.  
  785.     *--token = '\0';
  786.  
  787. }
  788.  
  789. /************************************************************************
  790.  * Function: echo
  791.  ************************************************************************/
  792. void echo(c)
  793. char    c;
  794. {
  795.     static int col = 11;
  796.     int i;
  797.  
  798.     if (c == '\t'){
  799.         do{
  800.             col++;
  801.             echochar(' ');
  802.         } while ((col <= max_col) && ((col % tab) != (11 % tab)));
  803.         col--;
  804.     }
  805.     else {
  806.         echochar(c);
  807.     }
  808.     if ( c == '\n' ){
  809.         col = 11;
  810.     }
  811.     else if (++col > max_col) {
  812.             col = 11;
  813.             paglin++;
  814.             echochar('\n');
  815.             for (i=1; i <= 11; i++){
  816.                 echochar(' ');
  817.             }
  818.     }
  819. }
  820.  
  821. /************************************************************************
  822.  * Function: echochar
  823.  ************************************************************************/
  824. void echochar(c)
  825. char    c;
  826. {
  827.     if (o_flg){
  828.         if(!echo_flag){
  829.             if (fprintf(f_lst_fil,"%c",c) == ERROR){
  830.                 lst_err();
  831.             }
  832.         }
  833.     }
  834.     else {
  835.         if(!echo_flag){
  836.             printf("%c",c);
  837.         }
  838.     }
  839. }
  840.  
  841.  
  842. /************************************************************************
  843.  * Function: get_token
  844.  * 'get_token' returns the next valid identifier or
  845.  * reserved word from a given file along with the
  846.  * character length of the token and an end-of-file
  847.  * indicator
  848.  ************************************************************************/
  849. int get_token(infile,g_token,g_toklen,g_eoflg,g_flg)
  850. FILE    *infile;
  851. char    *g_token;
  852. int        *g_toklen;
  853. int        *g_eoflg;
  854. int        g_flg;
  855. {
  856.     int        c;
  857.     char    *h_token;
  858.     char    tmpchr;
  859.  
  860.     h_token = g_token;
  861.  
  862. gtk:
  863.         *g_toklen = 0;
  864.         g_token = h_token;
  865.  
  866. /*
  867.     Scan and discard any characters until an alphabetic or
  868.     '_' (underscore) character is encountered or an end-of-file
  869.     condition occurs
  870. */
  871.  
  872.         
  873.     while ((!isalpha(c = rdchr(infile, g_eoflg, g_flg)))
  874.                                                     && !*g_eoflg
  875.                                                     &&  c != '_'
  876.                                                     &&  c != '0'
  877.                                                     &&  c != '#'){
  878.         if((c == OPENPAREN) && (!curlybrack_cnt) && (parenbrack_cnt == 1)){
  879.             return(FALSE);
  880.         }
  881.         if((c == SEMICOLEN) && (!curlybrack_cnt) && structflag) {
  882.             structflag = FALSE;
  883.         }
  884.     }
  885.                                                     
  886.     *g_token = c;
  887.     
  888.     if (*g_eoflg) {
  889.         return(FALSE);
  890.     }
  891.         
  892.     *g_toklen += 1;
  893.  
  894. /*
  895.     Scan and collect identified alpanumeric token until
  896.     a non-alphanumeric character is encountered or and
  897.     end-of-file condition occurs
  898. */
  899.  
  900.     if (g_flg) {
  901.         tmpchr = '.';
  902.     }
  903.     else {
  904.         tmpchr = '_';
  905.     }
  906.  
  907.     while ((isalpha(c=rdchr(infile,g_eoflg,g_flg))
  908.                                             || isdigit(c)
  909.                                             || c == '_'
  910.                                             || c == tmpchr)
  911.                                             && !*g_eoflg){
  912.         if (*g_toklen < MAX_LEN) {
  913.             *++g_token = c;
  914.             *g_toklen += 1;
  915.         }
  916.     }
  917.  
  918. /*
  919.     Check to see if a numeric hex or octal constant has
  920.     been encountered ... if so dump it and try again
  921. */
  922.  
  923.     if (*h_token == '0') {
  924.         goto gtk;
  925.     }
  926.  
  927.  
  928. /*
  929.     Tack a NULL character onto the end of the token
  930. */
  931.  
  932.     *++g_token = NULL;
  933.  
  934. /*
  935.     Screen out all #token strings except #include
  936. */
  937.     if (*h_token == '#' && strcmp(h_token,"#include")){
  938.         if(!strncmp(h_token,"#define", 7)){
  939.             defineflag = TRUE;
  940.         }
  941.         goto gtk;
  942.     }
  943.     
  944.  
  945.  
  946.     return(TRUE);
  947. }
  948.  
  949. /************************************************************************
  950.  * Function: fil_chr
  951.  * Get a character from the specified file, set f_eof flag to true if EOF.
  952.  ************************************************************************/
  953. int fil_chr(infile,f_eof)
  954. FILE *infile;
  955. int *f_eof;
  956. {
  957.     int        fc;
  958.  
  959.     fc=getc(infile);
  960.  
  961.     if (fc == EOF) {
  962.         *f_eof = TRUE;
  963.         fc = NULL;
  964.     }
  965.     return(fc);
  966. }
  967.  
  968. /************************************************************************
  969.  * Function: rdchr
  970.  * 'rdchr' returns the next valid character in a file
  971.  * and an end-of-file indicator. A valid character is
  972.  * defined as any which does not appear in either a
  973.  * commented or a quoted string ... 'rdchr' will correctly
  974.  * handle comment tokens which appear within a quoted
  975.  * string
  976.  ************************************************************************/
  977. int rdchr(infile, r_eoflg, rd_flg)
  978. int        *r_eoflg;
  979. FILE    *infile;
  980. int        rd_flg;
  981. {
  982.     int        c;
  983.     int        q_flg;                /* double quoted string flag            */
  984.     int        q1_flg;                /* single quoted string flag            */
  985.     int        cs_flg;                /* comment start flag                    */
  986.     int        ce_flg;                /* comment end flag                        */
  987.     int        c_cnt;                /* comment nesting level                */
  988.     int        t_flg;                /* transparency flag                    */
  989.  
  990.     q_flg = FALSE;
  991.     q1_flg = FALSE;
  992.     cs_flg = FALSE;
  993.     ce_flg = FALSE;
  994.     t_flg = FALSE;
  995.     c_cnt  = 0;
  996.  
  997. rch:
  998.  
  999. /*
  1000.     Fetch character from file
  1001. */
  1002.  
  1003.     /* Get a character from the specified file, set f_eof flag to true if EOF. */
  1004.     c=fil_chr(infile,r_eoflg);
  1005.     
  1006.     if (*r_eoflg) {
  1007.         check_paren(c);
  1008.         return(c);                /* EOF encountered                        */
  1009.     }
  1010.     if (c == '\n'){
  1011.         nl();
  1012.     }
  1013.     else {
  1014.         echo(c);
  1015.     }
  1016.  
  1017.     if (rd_flg){
  1018.         check_paren(c);
  1019.         return(c);
  1020.     }
  1021.  
  1022.     if (t_flg) {
  1023.         t_flg = !t_flg;
  1024.         goto rch;
  1025.     }
  1026.  
  1027.     if (c == '\\') {
  1028.         t_flg = TRUE;
  1029.         goto rch;
  1030.     }
  1031. /*
  1032.     If the character is not part of a quoted string
  1033.     check for and process commented strings...
  1034.     nested comments are handled correctly but unbalanced
  1035.     comments are not ... the assumption is made that
  1036.     the syntax of the program being xref'd is correct
  1037. */
  1038.  
  1039.     if (!q_flg && !q1_flg) {
  1040.         if (c == '*' && c_cnt && !cs_flg) {
  1041.             ce_flg = TRUE;
  1042.             goto rch;
  1043.         }
  1044.         if (c == '/' && ce_flg) {
  1045.             c_cnt -= 1;
  1046.             ce_flg = FALSE;
  1047.             goto rch;
  1048.         }
  1049.         ce_flg = FALSE;
  1050.         if (c == '/') {
  1051.             cs_flg = TRUE;
  1052.             goto rch;
  1053.         }
  1054.         if (c == '*' && cs_flg) {
  1055.             c_cnt += 1;
  1056.             cs_flg = FALSE;
  1057.             goto rch;
  1058.         }
  1059.         cs_flg = FALSE;
  1060.         if (c_cnt){
  1061.             goto rch;
  1062.         }
  1063.     }
  1064.  
  1065. /*
  1066.     Check for and process quoted strings
  1067. */
  1068.  
  1069.     if ( c == '"' && !q1_flg) {
  1070.         q_flg = !q_flg;        /* toggle quote flag                        */
  1071.         goto rch;
  1072.     }
  1073.     if (q_flg){
  1074.         goto rch;
  1075.     }
  1076.  
  1077.     if (c == '\'') {
  1078.         q1_flg = !q1_flg;    /* toggle quote flag                        */
  1079.         goto rch;
  1080.     }
  1081.     if (q1_flg) {
  1082.         goto rch;
  1083.     }
  1084.  
  1085. /*
  1086.     Valid character ... return to caller
  1087. */
  1088.     check_paren(c);
  1089.     return(c);
  1090. }
  1091.  
  1092. /************************************************************************
  1093.  * Function: chk_token
  1094.  ************************************************************************/
  1095. int chk_token(c_token)
  1096. char    *c_token;
  1097. {
  1098.     char    u_token[MAX_LEN];
  1099.     int        i;
  1100.  
  1101.         if (r_flg){
  1102.             return(TRUE);
  1103.         }
  1104.         i = 0;
  1105.         do {
  1106.             u_token[i] = toupper(c_token[i]);
  1107.         } while (c_token[i++] != NULL);
  1108.  
  1109.         switch(u_token[0]) {
  1110.             case 'A':
  1111.                 if (strcmp(u_token,"AUTO") == 0)
  1112.                     return(FALSE);
  1113.                 break;
  1114.             case 'B':
  1115.                 if (strcmp(u_token,"BREAK") == 0)
  1116.                     return(FALSE);
  1117.                 break;
  1118.             case 'C':
  1119.                 if (strcmp(u_token,"CHAR") == 0)
  1120.                     return (FALSE);
  1121.                 if (strcmp(u_token,"CONTINUE") == 0)
  1122.                     return (FALSE);
  1123.                 if (strcmp(u_token,"CASE") == 0)
  1124.                     return (FALSE);
  1125.                 break;
  1126.             case 'D':
  1127.                 if (strcmp(u_token,"DOUBLE") == 0)
  1128.                     return(FALSE);
  1129.                 if (strcmp(u_token,"DO") == 0)
  1130.                     return(FALSE);
  1131.                 if (strcmp(u_token,"DEFAULT") == 0)
  1132.                     return(FALSE);
  1133.                 break;
  1134.             case 'E':
  1135.                 if (strcmp(u_token,"EXTERN") == 0)
  1136.                     return(FALSE);
  1137.                 if (strcmp(u_token,"ELSE") == 0)
  1138.                     return(FALSE);
  1139.                 if (strcmp(u_token,"ENTRY") == 0)
  1140.                     return(FALSE);
  1141.                 if (strcmp(u_token,"ENUM") == 0)
  1142.                     return(FALSE);
  1143.                 break;
  1144.             case 'F':
  1145.                 if (strcmp(u_token,"FLOAT") == 0)
  1146.                     return(FALSE);
  1147.                 if (strcmp(u_token,"FOR") == 0)
  1148.                     return(FALSE);
  1149.                 break;
  1150.             case 'G':
  1151.                 if (strcmp(u_token,"GOTO") == 0)
  1152.                     return(FALSE);
  1153.                 break;
  1154.             case 'I':
  1155.                 if (strcmp(u_token,"INT") == 0)
  1156.                     return(FALSE);
  1157.                 if (strcmp(u_token,"IF") == 0)
  1158.                     return(FALSE);
  1159.                 break;
  1160.             case 'L':
  1161.                 if (strcmp(u_token,"LONG") == 0)
  1162.                     return(FALSE);
  1163.                 break;
  1164.             case 'R':
  1165.                 if (strcmp(u_token,"RETURN") == 0)
  1166.                     return(FALSE);
  1167.                 if (strcmp(u_token,"REGISTER") == 0)
  1168.                     return(FALSE);
  1169.                 break;
  1170.             case 'S':
  1171.                 if (strcmp(u_token,"STRUCT") == 0) {
  1172.                     return(FALSE);
  1173.                 }
  1174.                 if (strcmp(u_token,"SHORT") == 0)
  1175.                     return(FALSE);
  1176.                 if (strcmp(u_token,"STATIC") == 0)
  1177.                     return(FALSE);
  1178.                 if (strcmp(u_token,"SIZEOF") == 0)
  1179.                     return(FALSE);
  1180.                 if (strcmp(u_token,"SWITCH") == 0)
  1181.                     return(FALSE);
  1182.                 break;
  1183.             case 'T':
  1184.                 if (strcmp(u_token,"TYPEDEF") == 0) {
  1185.                     structflag = TRUE;
  1186.                     return(FALSE);
  1187.                 }
  1188.                 break;
  1189.             case 'U':
  1190.                 if (strcmp(u_token,"UNION") == 0)
  1191.                     return(FALSE);
  1192.                 if (strcmp(u_token,"UNSIGNED") == 0)
  1193.                     return(FALSE);
  1194.                 break;
  1195.             case 'V':
  1196.                 if (strcmp(u_token,"VOID") == 0)
  1197.                     return(FALSE);
  1198.                 break;
  1199.             case 'W':
  1200.                 if (strcmp(u_token,"WHILE") == 0)
  1201.                     return(FALSE);
  1202.                 break;
  1203.         }
  1204.         return(TRUE);
  1205. }
  1206.  
  1207. /************************************************************************
  1208.  * Function: put_token
  1209.  * Install parsed token and line reference in linked structure
  1210.  ************************************************************************/
  1211. void put_token(p_token,p_ref)
  1212. char    *p_token;
  1213. int        p_ref;
  1214.     {
  1215.     int        hsh_index;
  1216.     int        i;
  1217.     int        j;
  1218.     int        d;
  1219.     int        found;
  1220.     struct    id_blk *idptr;
  1221.     struct    rf_blk *rfptr;
  1222.     struct    id_blk *alloc_id();
  1223.     struct    rf_blk *alloc_rf();
  1224.     struct    rf_blk *add_rf();
  1225.  
  1226.     if (l_flg){
  1227.         return;
  1228.     }
  1229.  
  1230.     /* Hashing algorithm is far from            */
  1231.     /* optimal but is adequate for a            */
  1232.     /* memory-bound index vector!                */
  1233.     j=0;
  1234.     for (i=0; p_token[i] != NULL; i++) {
  1235.         j = j * 10 + p_token[i];
  1236.     }
  1237.     hsh_index = abs(j) % MAX_WRD;
  1238.     found = FALSE;
  1239.     d = 1;
  1240.     do {
  1241.         idptr = id_vector[hsh_index];
  1242.         if (idptr == NULL) {
  1243.             id_cnt++;
  1244.             idptr = id_vector[hsh_index] = alloc_id(p_token);
  1245.             chain_alpha(idptr,p_token);
  1246.             idptr->top_lnk = idptr->lst_lnk = alloc_rf(p_ref);
  1247.             found = TRUE;
  1248.         }
  1249.         else if (strcmp(p_token,idptr->id_name) == 0) {
  1250.                 idptr->lst_lnk = add_rf(idptr->lst_lnk,p_ref);
  1251.                 found = TRUE;
  1252.         }
  1253.         else {
  1254.             hsh_index += d;
  1255.             d += 2;
  1256.             rhsh_cnt++;
  1257.             if (hsh_index >= MAX_WRD) {
  1258.                 hsh_index -= MAX_WRD;
  1259.             }
  1260.             if (d == MAX_WRD) {
  1261.                 printf("\nERROR: Symbol table overflow\n");
  1262.                 exit(0);
  1263.             }
  1264.         }
  1265.     } while (!found);
  1266. }
  1267.  
  1268. /************************************************************************
  1269.  * Function: chain_alpha
  1270.  ************************************************************************/
  1271. void chain_alpha(ca_ptr,ca_token)
  1272. struct    id_blk *ca_ptr;
  1273. char    *ca_token;
  1274. {
  1275.     char    c;
  1276.     int        f;
  1277.     struct    id_blk *cur_ptr;
  1278.     struct    id_blk *lst_ptr;
  1279.  
  1280.     c = ca_token[0];
  1281.     if (c == '_'){
  1282.         c = 0;
  1283.     }
  1284.     else if (isupper(c)) {
  1285.         c=1+((c-'A')*2);
  1286.     }
  1287.     else {
  1288.         c=2+((c-'a')*2);
  1289.     }
  1290.  
  1291.     if (alpha_vector[c].alpha_top == NULL) {
  1292.         alpha_vector[c].alpha_top = alpha_vector[c].alpha_lst = ca_ptr;
  1293.         ca_ptr->alpha_lnk = NULL;
  1294.         return;
  1295.     }
  1296.  
  1297. /*    check to see if new id_blk should be inserted between
  1298.     the alpha_vector header block and the first id_blk in
  1299.     the current alpha chain
  1300. */
  1301.  
  1302.     if (strcmp(alpha_vector[c].alpha_top->id_name,ca_token) > 0) {
  1303.         ca_ptr->alpha_lnk=alpha_vector[c].alpha_top;
  1304.         alpha_vector[c].alpha_top=ca_ptr;
  1305.         return;
  1306.     }
  1307.  
  1308.     if (strcmp(alpha_vector[c].alpha_lst->id_name,ca_token) < 0) {
  1309.         alpha_vector[c].alpha_lst->alpha_lnk = ca_ptr;
  1310.         ca_ptr->alpha_lnk = NULL;
  1311.         alpha_vector[c].alpha_lst=ca_ptr;
  1312.         return;
  1313.     }
  1314.  
  1315.     cur_ptr = alpha_vector[c].alpha_top;
  1316.     while (strcmp(cur_ptr->id_name,ca_token) < 0) {
  1317.         lst_ptr = cur_ptr;
  1318.         cur_ptr = lst_ptr->alpha_lnk;
  1319.     }
  1320.  
  1321.     lst_ptr->alpha_lnk = ca_ptr;
  1322.     ca_ptr->alpha_lnk = cur_ptr;
  1323.     return;
  1324. }
  1325.  
  1326. /************************************************************************
  1327.  * Function: alloc_id
  1328.  ************************************************************************/
  1329. struct id_blk *alloc_id(aid_token)
  1330. char    *aid_token;
  1331. {
  1332.     int        ai;
  1333.     struct    id_blk *aid_ptr;
  1334.  
  1335.     if ((aid_ptr = alloc(sizeof(struct id_blk))) == 0)
  1336.         {
  1337.         printf("\nERROR: Unable to allocate identifier block\n");
  1338.         exit(0);
  1339.         }
  1340.     ai=0;
  1341.     do {
  1342.         aid_ptr->id_name[ai] = aid_token[ai];
  1343.     } while (aid_token[ai++] != NULL);
  1344.  
  1345.     return (aid_ptr);
  1346. }
  1347.  
  1348. /************************************************************************
  1349.  * Function: alloc_rf
  1350.  ************************************************************************/
  1351. struct rf_blk *alloc_rf(arf_ref)
  1352. int        arf_ref;
  1353. {
  1354.     int        ri;
  1355.     struct    rf_blk *arf_ptr;
  1356.  
  1357.     if ((arf_ptr = alloc(sizeof(struct rf_blk))) == 0) {
  1358.         printf("\nERROR: Unable to allocate reference block\n");
  1359.         exit(0);
  1360.     }
  1361.     arf_ptr->ref_item[0] = arf_ref;
  1362.     arf_ptr->ref_cnt = (char*)1;
  1363.     for (ri=1;ri<MAX_REF;ri++) {
  1364.         arf_ptr->ref_item[ri] = NULL;
  1365.     }
  1366.     return (arf_ptr);
  1367. }
  1368.  
  1369. /************************************************************************
  1370.  * Function: add_rf
  1371.  ************************************************************************/
  1372. struct rf_blk *add_rf(adr_ptr,adr_ref)
  1373. struct    rf_blk *adr_ptr;
  1374. int        adr_ref;
  1375. {
  1376.     struct    rf_blk *tmp_ptr;
  1377.  
  1378.     tmp_ptr = adr_ptr;
  1379.     if (adr_ptr->ref_cnt == (char*)MAX_REF) {
  1380.         tmp_ptr = adr_ptr->ref_cnt = (char*)alloc_rf(adr_ref);
  1381.     }
  1382.     else{
  1383.         adr_ptr->ref_item[(int)(adr_ptr->ref_cnt++)] = adr_ref;
  1384.     }
  1385.     return (tmp_ptr);
  1386. }
  1387.  
  1388. /************************************************************************
  1389.  * Function: prnt_tbl
  1390.  ************************************************************************/
  1391. void prnt_tbl()
  1392. {
  1393.     int        prf_cnt;
  1394.     int        pti;
  1395.     int        pref;
  1396.     int        lin_cnt;
  1397.     char    save_1st;
  1398.     struct    id_blk *pid_ptr;
  1399.     struct    rf_blk *ptb_ptr;
  1400.     int        saved_echo_flag;
  1401.  
  1402.     save_1st = NULL;
  1403.     prt_ref = TRUE;
  1404.     prt_hdr();
  1405.     saved_echo_flag = echo_flag;
  1406.     /* echo_flag = FALSE; */
  1407.     for (pti=0;pti<MAX_ALPHA;pti++) {
  1408.         if ((pid_ptr = alpha_vector[pti].alpha_top) != NULL) {
  1409.             do {
  1410.                 if (save_1st != pid_ptr->id_name[0]) {
  1411.                     if(!nofuncnameflag){
  1412.                         nl();
  1413.                     }
  1414.                     save_1st = pid_ptr->id_name[0];
  1415.                 }
  1416.                 if ((!echo_flag) && o_flg) {
  1417.                     if (fprintf(f_lst_fil,"%-33.32s: ",pid_ptr->id_name) == ERROR){
  1418.                         lst_err();
  1419.                     }
  1420.                 }
  1421.                 else if(!echo_flag){
  1422.                     printf("%-33.32s: ",pid_ptr->id_name);
  1423.                 }
  1424.                 ptb_ptr=pid_ptr->top_lnk;
  1425.                 lin_cnt=prf_cnt=0;
  1426.                 do {
  1427.                     if (prf_cnt == MAX_REF) {
  1428.                         prf_cnt=0;
  1429.                         ptb_ptr = (struct rf_blk *)ptb_ptr->ref_cnt;
  1430.                     }
  1431.                     if (((int)ptb_ptr) > MAX_REF) {
  1432.                         if ((pref=ptb_ptr->ref_item[prf_cnt++]) != 0) {
  1433.                             if (o_flg) {
  1434.                                 if ((!echo_flag) && (fprintf(f_lst_fil,"%4d ",pref) == ERROR)) {
  1435.                                     lst_err();
  1436.                                 }
  1437.                             }
  1438.                             else if(!echo_flag){
  1439.                                 printf("%4d ",pref);
  1440.                             }
  1441.                             if (++lin_cnt == REFS_PER_LINE) {
  1442.                                 if(!nofuncnameflag){
  1443.                                     nl();
  1444.                                     if ((!echo_flag) && o_flg) {
  1445.                                         if (fprintf(f_lst_fil,"                                   ") == ERROR) {
  1446.                                             lst_err();
  1447.                                         }
  1448.                                     }
  1449.                                     else if(!echo_flag){
  1450.                                         printf("                                   ");
  1451.                                     }
  1452.                                 }
  1453.                                 lin_cnt=0;
  1454.                             }
  1455.                             
  1456.                         }
  1457.                     } 
  1458.                     else {
  1459.                         pref=0;
  1460.                     }
  1461.                 } while (pref);
  1462.                 nl();
  1463.             } while ((pid_ptr=pid_ptr->alpha_lnk) != NULL);
  1464.         }
  1465.     }/*for*/
  1466.         
  1467.     echo('\n');
  1468.     echo_flag = saved_echo_flag;
  1469. }
  1470.  
  1471. /************************************************************************
  1472.  * Function: prt_hdr
  1473.  ************************************************************************/
  1474. void prt_hdr()
  1475. {
  1476.     if (pagno++ != 0) {
  1477.         if(!nofuncnameflag){
  1478.             echo('\n');
  1479.             echo( FF );
  1480.         }
  1481.     }
  1482.     if (o_flg){
  1483.         if(!nofuncnameflag){
  1484.             if (fprintf(f_lst_fil, "XC ... 'C' Concordance Utility   %-20s       Page %d",
  1485.                                                                 gbl_fil,pagno) == ERROR){
  1486.                 lst_err();
  1487.             }
  1488.         }
  1489.     }
  1490.     else {
  1491.         if(!nofuncnameflag){
  1492.             printf("XC ... 'C' Concordance Utility   %-20s       Page %d",gbl_fil,pagno);
  1493.         }
  1494.     }
  1495.     if(!nofuncnameflag){
  1496.         echo('\n');
  1497.     }
  1498.     paglin = 3;
  1499.     nl();
  1500. }
  1501.  
  1502. /************************************************************************
  1503.  * Function: nl
  1504.  ************************************************************************/
  1505. void nl()
  1506. {
  1507.     echo('\n');
  1508.     if (++paglin >= LINES_PER_PAGE) {
  1509.         prt_hdr();
  1510.     }
  1511.     else if (!prt_ref) {
  1512.         if(defineflag && (lastnonspacechar != 0x5C)){
  1513.             defineflag = FALSE;
  1514.             wrote_macro = FALSE;
  1515.         }
  1516.         if (o_flg) {
  1517.             if(!echo_flag){
  1518.                 if (fprintf(f_lst_fil,"%-4d %4d: ",    ++linum,++edtnum) == ERROR){
  1519.                     lst_err();
  1520.                 }
  1521.             }
  1522.             else {
  1523.                     ++linum; ++edtnum;
  1524.             }
  1525.         }
  1526.         else {
  1527.             if(!echo_flag){
  1528.                 printf("%-4d %4d: ",    ++linum,++edtnum);
  1529.             }
  1530.             else {
  1531.                 ++linum; ++edtnum;
  1532.             }
  1533.         }
  1534.         if (o_flg){
  1535.             if (linum % 60 == 1) {
  1536.                 if(!echo_flag){
  1537.                     printf("\n<%4d> ",linum);
  1538.                 }
  1539.             }
  1540.             else {
  1541.                 if(!echo_flag){
  1542.                     printf(".");
  1543.                 }
  1544. #ifdef Lattice
  1545.                 fflush(stdout);
  1546. #endif
  1547.             }
  1548.         }
  1549.  
  1550.     }
  1551.     return;
  1552. }
  1553.  
  1554. /************************************************************************
  1555.  * Function: abs
  1556.  ************************************************************************/
  1557. #ifndef Lattice
  1558. int    abs(i)
  1559. int        i;
  1560. {
  1561.     if (i<0)
  1562.         return(-i);
  1563.     else
  1564.         return( i);
  1565. }
  1566. #endif
  1567.  
  1568. /************************************************************************
  1569.  * Function: atoi
  1570.  * cvt ascii to int or long
  1571.  ************************************************************************/
  1572. #ifdef Lattice
  1573. long    atoi(s)
  1574. char    *s;
  1575. {
  1576.     long    n;
  1577.     int        sign = 0;
  1578.  
  1579.     while (*s==' ' || *s=='\t')
  1580.         ++s;                /* move over blanks & tabs                    */
  1581.     if (*s=='-')
  1582.         sign=1;
  1583.     else
  1584.         if (*s!='+')
  1585.             --s;
  1586.     ++s;                    /* skip sign                                */
  1587.     for (n=0; *s >= '0' && *s<='9'; )
  1588.         n = n * 10 + (*s++ - '0');
  1589.     if (sign)
  1590.         n = -n;
  1591.     return n;
  1592. }
  1593. #endif
  1594.  
  1595. /************************************************************************
  1596.  * Function: alloc
  1597.  ************************************************************************/
  1598. char* alloc(i)
  1599. int        i;
  1600. {
  1601.     return(malloc(i));
  1602. }
  1603.  
  1604.